using System;
using System.Collections.Generic;
using System.Text;

namespace RaidLog.Engine.Armory
{
    public class ArmoryUtil
    {
        public static character_talents.pageCharacterInfo GetTalentInfo(string name)
        {
            return Query<character_talents.page>("character-talents", "r=Perenolde&n=" + name).characterInfo[0];
        }

        public static void GetArenaTeamInfo(string name)
        {
            //System.Windows.Forms.MessageBox.Show(Query("team-info", "r=Perenolde&n=" + name));
        }

        public static item_tooltip.pageItemTooltip FindItemInfo(string name)
        {
            //search.xml?searchQuery=Leggings+of+the+Fallen+Champion
            armorySearch.page _page = Query<armorySearch.page>("search",
                "searchQuery=" + urlEncode(name) + "&searchType=items");
            if (null != _page &&
                null != _page.armorySearch &&
                null != _page.armorySearch.searchResults &&
                null != _page.armorySearch.searchResults.items &&
                0 != _page.armorySearch.searchResults.items.Length &&
                null != _page.armorySearch.searchResults.items[0])
            {
                return GetItemInfo(_page.armorySearch.searchResults.items[0].id);
            }
            return null;
        }

        private static string urlEncode(string name)
        {
            return name.Replace(" ", "+").Replace("'", "%27");
        }

        public static item_tooltip.pageItemTooltip GetItemInfo(string id)
        {
            item_tooltip.page _page = Query<item_tooltip.page>("item-tooltip", "i=" + id);
            if (null == _page || null == _page.itemTooltip || 1 != _page.itemTooltip.Length)
            {
                if (null == _page ||
                    null == _page.itemTooltips ||
                    1 != _page.itemTooltips.Length ||
                    null == _page.itemTooltips[0].itemTooltip ||
                    1 != _page.itemTooltips[0].itemTooltip.Length) return null;

                return _page.itemTooltips[0].itemTooltip[0];
            }
            return _page.itemTooltip[0];
        }

        public static character_sheet.pageCharacterInfo GetCharInfo(string name)
        {
            character_sheet.page _page = Query<character_sheet.page>("character-sheet", "r=Perenolde&n=" + urlEncode(name));
            if (null == _page || null == _page.characterInfo || 1 != _page.characterInfo.Length) return null;
            return _page.characterInfo[0];
        }

        public static guild_info.pageGuildInfoGuild GetGuildInfo(string name)
        {
            guild_info.page _page = Query<guild_info.page>("guild-info", "r=Perenolde&n=" + urlEncode(name));
            if (null == _page || null == _page.guildInfo || 1 != _page.guildInfo.Length) return null;
            return _page.guildInfo[0];
        }

        public static TType Query<TType>(string queryType, string name) where TType : new()
        {
            String xmlData = Query(queryType, name);
            return Deserialize<TType>(xmlData);
        }

        public static TType Deserialize<TType>(string xmlData) //where TType : new()
        {
            if (String.IsNullOrEmpty(xmlData)) return default(TType);
            System.Xml.Serialization.XmlSerializer xmlSerializer = new System.Xml.Serialization.XmlSerializer(typeof(TType));
            try
            {
                object o = xmlSerializer.Deserialize(new System.IO.StringReader(xmlData));
                return (TType)o;
            }
            catch (System.InvalidOperationException ex)
            {
                System.Diagnostics.Trace.TraceError(ex.Message);
                return default(TType);
            }
        }

        public static String Serialize<TType>(TType xmlData) //where TType : new()
        {
            if (null == xmlData) return null;
            System.Xml.Serialization.XmlSerializer xmlSerializer = new System.Xml.Serialization.XmlSerializer(typeof(TType));
            try
            {
                System.IO.StringWriter stringWriter = new System.IO.StringWriter();
                xmlSerializer.Serialize(stringWriter, xmlData);
                return stringWriter.ToString();
            }
            catch (System.InvalidOperationException ex)
            {
                System.Diagnostics.Trace.TraceError(ex.Message);
                return null;
            }
        }

        public static string Query(string queryType, string name)
        {
            string uri = String.Format("http://12.129.242.20/{0}.xml?{1}", queryType, name);
            string file = "cache/" + FileCharFilter(String.Format("{0} {1}.xml", queryType, name));
            if (!System.IO.Directory.Exists("cache")) System.IO.Directory.CreateDirectory("cache");
            if (System.IO.File.Exists(file)) return System.IO.File.ReadAllText(file);
            System.Net.WebClient webClient = new System.Net.WebClient();
            webClient.Headers.Add("user-agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1) Gecko/20061010 Firefox/2.0' ");

            try
            {
                string response = webClient.DownloadString(uri);
                System.IO.File.WriteAllText(FileCharFilter(file), response);
                System.Diagnostics.Trace.WriteLine("Web request: " + uri);
                return response;
            }
            catch (System.Net.WebException ex)
            {
                System.Diagnostics.Trace.TraceError(ex.Message);
                return null;
            }
        }

        private static string FileCharFilter(string file)
        {
            return file.Replace(":", "-");
        }
    }
}
